#pragma once
#include <list>
#include <sstream>
#include <ctime>
using namespace std;
#include "SkypeClient.h"
#include "Settings.h"
#include "ClientsManager.h"

class ClientResult
{
public:
	enum ResultType{RES_TYPE_LOGINED, RES_TYPE_ONLINE, RES_TYPE_FAILED,RES_TYPE_TIMEOUT,RES_TYPE_REFUSED, RES_TYPE_BUSY, RES_TYPE_MISSED, RES_TYPE_FINISHED};

	const string toString()const;
	const string callerId() const {
		return m_callerId;
	}
	void setCallerId(const string& value) {
		m_callerId = value;
	}
	const string pwd() const {
		return m_pwd;
	}
	void setPwd(const string& value) {
		m_pwd = value;
	}
	const string calleeId() const {
		return m_calleeId;
	}
	void setCalleeId(const string& value) {
		m_calleeId = value;
	}
	ResultType type() const {
		return m_type;
	}
	void setType(ResultType value) {
		m_type = value;
	}
	const string msg() const {
		return m_msg;
	}
	void setMsg(const string& value) {
		m_msg = value;
	}
	time_t time() const {
		return m_time;
	}
	void setTime(time_t value) {
		m_time = value;
	}

private:
	string m_callerId;
	string m_pwd;
	string m_calleeId;
	ResultType m_type;
	string m_msg;
	time_t m_time;
	friend bool operator < (const ClientResult& left, const ClientResult& right);
};
bool operator < (const ClientResult& left, const ClientResult& right);


class CallingCenter : public ClientsManagerObserver
{
public:
	CallingCenter(void);
	~CallingCenter(void);
	void addUser(const UserInfo*);
	void addCaller(Caller*);
	void addCallee(Callee*);
	void addCallers(const CallerList&);
	void addCallees(const CalleeList&);
	void callerToString(string& )const;
	void calleeToString(string& )const;
	void loopCallerCall(ClientsManager* clientMan);
	void loopCalleeCall(ClientsManager* clientMan);
	void Result(string&);
	void clearResult();
	void addResult(const SkypeClient* client, ClientResult::ResultType type, const string& msg);

	// ClientsManagerObserver
	void clientLogined(const SkypeClient* client);
	void clientOnline(const SkypeClient* client);
	void clientTimeOut(const SkypeClient* client);
	void clientCallRefused(const SkypeClient* client);
	void clientCallFailed(const SkypeClient* client);
	void clientCallBusy(const SkypeClient* client);
	void clientCallMissed(const SkypeClient* client);
	void clientCallFinished(const SkypeClient* client);

private:
	// TODO modify UserInfo to Caller and Callee
	CallerList m_availableCallers;
	CalleeList m_availableCallees;

	// record every calling into m_callings
	// TODO add recording of callings.
	list<CallingData> m_callings;

	list<ClientResult> m_callingResult;
	static const int m_delayTime;
	CRITICAL_SECTION m_callResultSection;
};
